#include "jUdp.hh"
#include <pthread.h>

void udpSocket_t::sendData(const char *ip, uint16_t port, void *data, uint16_t len)
{
    struct sockaddr_in servAddr;

    if( 0 >= fd )
    {
        printf("socket not initd,! \n");
        return;
    }
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(port);
    inet_aton(ip, &servAddr.sin_addr);

    int num = sendto(fd, data, len, 0, (struct sockaddr *)&servAddr, sizeof(servAddr));
    if(num != len)
        printf("udpSocket_t::sendData udp send err num is:%d \n", num);
}

void udpSocket_t::sendDataToLastSocket(void *data, uint16_t len)
{
    int num = sendto(fd, data, len, 0, (struct sockaddr *)&cliAddr, sizeof(cliAddr));
    if(num != len)
        printf("udpSocket_t::sendDataToLastSocket error  udp send err num is:%d \n", num);
}


udpSocket_t::udpSocket_t(uint16_t port)
{
    int servSocket;
    struct sockaddr_in servAddr;

    if((servSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        printf("udp socket err \n");
        fflush(stdout);
        abort();
    }
    this->fd = servSocket;

    revBuff = malloc(buffLen);

    bzero(&servAddr,sizeof(servAddr));

    servAddr.sin_family    = AF_INET;
    servAddr.sin_port = htons(port);
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(servSocket,(struct sockaddr *)&servAddr,sizeof(servAddr)) < 0)
    {
        printf("udpSocket_t: udp port %d bind err. \n", port);
        exit(1);
    }

    int r = pthread_create(&updRevTid, nullptr, udpThread, this);
    if (r)
    {
        perror("udpSocket_t: pthread_create()");
        return;
    }
}

void *udpSocket_t::udpThread(void *p)
{
    udpSocket_t *pThis = (udpSocket_t *)p;

    int nbytes;

    int addrLen = sizeof(pThis->cliAddr);

    while(1)
    {
        if( (nbytes = recvfrom( pThis->fd, pThis->revBuff, pThis->buffLen, 0, (struct sockaddr *)&pThis->cliAddr,  (socklen_t*)&addrLen)) < 0)
        {
            printf("UDP 接收数据出错！！！！\n");
            exit(-1);
        }
        //printf(" 收到 UDP 数据！ len:%d\n", nbytes);
        //udpCallback( cliAddr.sin_addr, cliAddr.sin_port, revBuff, nbytes );

        if( nullptr != pThis->revDataCB )
        {
            pThis->revDataCB(pThis->cliAddr.sin_addr, pThis->cliAddr.sin_port, pThis->revBuff, nbytes, pThis->pDev);
        }


        //printf("\n---From %s:%d\n", inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port));
        //printf("Recv: %s\nlength: %d\n\n", revBuff, nbytes);
        //memset(revBuff, 0, BUFF_SIZE);
    }


    return  0;
}

